package com.wingsboat.common.datasource.utils;

import com.wingsboat.common.core.annotation.WBEntity;
import com.wingsboat.common.core.constant.Constants;
import com.wingsboat.common.core.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * @author wangzhong
 * @description: 层级编码生成器
 * @date 2024/4/24 19:44
 */
@Component
public class TotalCodeFactory {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 生成下一个层级编号。
     *
     * @param tableName 数据表名
     * @param parentCode 父级编号，如果为空则生成顶级编号
     * @return 新生成的层级编号
     * 要不要加 synchronized？
     */
    public String nextCode(String tableName, String parentCode) {
        if (parentCode == null || parentCode.isEmpty() || parentCode.equals(Constants.HIGHEST_TOTAL_CODE)) {
            // 生成顶级编号
            return generateTopLevelCode(tableName);
        } else {
            // 查询最大子编号并生成下一个
            return findMaxChildSequence(tableName, parentCode);
        }
    }

    /**
     * 生成下一个层级编号。
     *
     * @param clazz 实体类
     * @param parentCode 父级编号，如果为空则生成顶级编号
     * @return 新生成的层级编号
     * 要不要加 synchronized？
     */
    public String nextCode(Class clazz, String parentCode) {
        WBEntity entity = (WBEntity) clazz.getAnnotation(WBEntity.class);
        if(Objects.isNull(entity)){
            throw new ServiceException("实体类没有增加WBEntity注解");
        }
        String tableName = entity.value();
        if (parentCode == null || parentCode.isEmpty() || parentCode.equals(Constants.HIGHEST_TOTAL_CODE)) {
            // 生成顶级编号
            return generateTopLevelCode(tableName);
        } else {
            // 查询最大子编号并生成下一个
            return findMaxChildSequence(tableName, parentCode);
        }
    }

    /**
     * 生成顶级编号
     * @param tableName 数据表名
     * @return
     */
    public String generateTopLevelCode(String tableName) {
        String query = "SELECT MAX(total_code) AS seq FROM " + tableName + " WHERE parent_code = ?";
        Integer maxTotalCode = jdbcTemplate.queryForObject(query, new Object[]{Constants.HIGHEST_TOTAL_CODE}, Integer.class);
        if (maxTotalCode == null) {
            return "001";
        } else {
            return String.format("%03d", maxTotalCode + 1);
        }
    }

    /**
     * 获取最大编码
     * @param tableName 数据表名
     * @param parentCode 父级编号
     * @return
     */
    public String findMaxChildSequence(String tableName, String parentCode) {
        String query = "SELECT MAX(RIGHT(total_code, 3)) AS seq FROM " + tableName + " WHERE parent_code = ?";
        String likePattern = parentCode;
        // 查询最大子编号并生成下一个
        Integer maxChildSeq = jdbcTemplate.queryForObject(query, new Object[]{likePattern}, Integer.class);

        if (maxChildSeq == null) {
            return parentCode + "001";
        } else {
            String nextCode = parentCode + String.format("%03d", maxChildSeq + 1);
            return nextCode;
        }
    }
}
